package com.mikufufu.blog.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mikufufu.blog.common.cache.RedisCache;
import com.mikufufu.blog.common.constant.Constant;
import com.mikufufu.blog.common.constant.RedisKey;
import com.mikufufu.blog.model.vo.admin.EmailConfig;
import com.mikufufu.blog.model.vo.api.StatisticsVO;
import com.mikufufu.blog.model.vo.api.WebSiteVO;
import com.mikufufu.blog.utils.AesUtils;
import com.mikufufu.blog.utils.SpringUtils;
import com.mikufufu.blog.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mikufufu.blog.mapper.SysSettingMapper;
import com.mikufufu.blog.model.entity.SysSetting;
import com.mikufufu.blog.service.SysSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 系统设置 服务实现类
 * 
 */
@Service
@Slf4j
public class SysSettingServiceImpl extends ServiceImpl<SysSettingMapper, SysSetting> implements SysSettingService {



    /**
     * 获取存储编码。首先尝试从缓存中获取存储编码，如果缓存中不存在，则从数据库中查询，并将查询结果存入缓存。
     *
     * @return 返回存储编码，如果不存在则返回null。
     */
    @Override
    public String getStorageCode() {

        // 从数据库中查询存储编码
        SysSetting storageSetting = this.getOne(new QueryWrapper<SysSetting>().lambda()
                .eq(SysSetting::getCode, Constant.STORAGE_SETTING_CODE)
                .eq(SysSetting::getStatus, 0)
        );
        if (StringUtils.isNotEmpty(storageSetting)) {
            return storageSetting.getValue();
        }
        return null;
    }

    @Override
    public Boolean updateStorageCode(String storageCode) {
        if (StringUtils.isBlank(storageCode)) {
            throw new RuntimeException("存储编码不能为空");
        }
        return this.update(new LambdaUpdateWrapper<SysSetting>()
                .set(SysSetting::getValue, storageCode)
                .eq(SysSetting::getCode, Constant.STORAGE_SETTING_CODE)
        );
    }

    @Override
    public Boolean setMail(EmailConfig emailConfig) {
        try {
            emailConfig.setPassword(AesUtils.encrypt(emailConfig.getPassword()));
        } catch (Exception e) {
            log.error("邮件密码加密失败", e);
            throw new RuntimeException(e);
        }
        SysSetting sysSetting = this.getOne(new QueryWrapper<SysSetting>().lambda()
                .eq(SysSetting::getCode, Constant.SYS_EMAIL_SETTING_CODE)
                .eq(SysSetting::getStatus, 0)
        );
        if (StringUtils.isNotEmpty(sysSetting)) {
            sysSetting.setValue(JSON.toJSONString(emailConfig));
            return this.updateById(sysSetting);
        }
        sysSetting = new SysSetting();
        sysSetting.setCode(Constant.SYS_EMAIL_SETTING_CODE);
        sysSetting.setValue(JSON.toJSONString(emailConfig));
        sysSetting.setConfigName("系统邮件设置");
        sysSetting.setRemark("系统邮件设置");
        sysSetting.setStatus(0);
        this.save(sysSetting);
        return true;
    }

    @Override
    public EmailConfig getMail() {
        SysSetting sysSetting = this.getOne(new QueryWrapper<SysSetting>().lambda()
                .eq(SysSetting::getCode, Constant.SYS_EMAIL_SETTING_CODE)
                .eq(SysSetting::getStatus, 0)
        );
        if (StringUtils.isNotEmpty(sysSetting)) {
            EmailConfig emailConfig = JSON.parseObject(sysSetting.getValue(), EmailConfig.class);
            try {
                emailConfig.setPassword(AesUtils.decrypt(emailConfig.getPassword()));
            } catch (Exception e) {
                log.error("邮件密码解密失败", e);
                throw new RuntimeException(e);
            }
            return emailConfig;
        }
        return null;
    }

    @Override
    public WebSiteVO getWebSiteVO() {
        SysSetting sysSetting = this.getOne(new LambdaQueryWrapper<SysSetting>().eq(SysSetting::getCode, Constant.WEB_SITE_CODE));
        String website = sysSetting.getValue();
        WebSiteVO webSiteVO = JSON.parseObject(website, WebSiteVO.class);
        webSiteVO.setDeployTime(SpringUtils.getStartupTime());
        webSiteVO.setSystem(System.getProperty("os.name"));

        StatisticsVO statistics = new StatisticsVO();
        statistics.setArticleCount((long) RedisCache.get(RedisKey.ARTICLE_COUNT));
        statistics.setWordCount((long) RedisCache.get(RedisKey.WORD_COUNT));
        statistics.setCommentCount((long) RedisCache.get(RedisKey.COMMENT_COUNT));
        statistics.setCategoryCount((long) RedisCache.get(RedisKey.CATEGORY_COUNT));
        statistics.setVisitCount(this.getVisitCount());

        webSiteVO.setStatistics(statistics);
        return webSiteVO;
    }

    private Integer getVisitCount() {
        Integer count = (Integer) RedisCache.get(RedisKey.VISIT_COUNT);
        if (count != null){
            count = count + 1;
            RedisCache.set(RedisKey.VISIT_COUNT, count);
            return count;
        }
        SysSetting visitCount = this.getOne(new LambdaQueryWrapper<SysSetting>().eq(SysSetting::getCode, Constant.GUEST_ROLE_COUNT_CODE));
        if (StringUtils.isEmpty(visitCount)){
            visitCount = new SysSetting();
            visitCount.setCode(Constant.GUEST_ROLE_COUNT_CODE);
            visitCount.setValue("1");
            visitCount.setConfigName("访问量");
            visitCount.setRemark("访问量");
            visitCount.setStatus(0);
            RedisCache.set(RedisKey.VISIT_COUNT, 1);
            this.save(visitCount);
            return 1;
        }
        count = Integer.parseInt(visitCount.getValue()) + 1;
        RedisCache.set(RedisKey.VISIT_COUNT, count);
        visitCount.setValue(String.valueOf( count));
        this.updateById(visitCount);
        return count;
    }

    @Override
    public Boolean saveWebInfo(WebSiteVO webSiteVO) {
        SysSetting setting = this.getOne(new LambdaQueryWrapper<SysSetting>().eq(SysSetting::getCode, Constant.WEB_SITE_CODE));
        if (StringUtils.isEmpty(setting)) {
            setting = new SysSetting();
        }
        setting.setCode(Constant.WEB_SITE_CODE);
        setting.setConfigName("网站信息");
        setting.setRemark("网站信息");
        setting.setStatus(0);
        setting.setValue(JSON.toJSONString(webSiteVO));
        return this.saveOrUpdate(setting);
    }

}
